﻿@layout BaseLayout
@inherits LayoutComponentBase
@implements IAsyncDisposable
@using Masa.Blazor.Extensions

<NavDrawer @bind-Value="_showDrawer"
           RTL="MasaBlazor.RTL" />

<MScrollToTarget RootMarginTop="@($"-{Offset + 4}px")"
                 AutoRootMargin="AutoRootMargin.Bottom"
                 Offset="@Offset">
    <MMain Class="doc-main">
        @Body
    </MMain>

    <Toc RTL="@MasaBlazor.RTL"
         ActiveItem="@context.ActiveTarget" />
</MScrollToTarget>

<FabTransition>
    <MButton Show="_showBackTop" Large Fab Fixed Bottom Right Class="transition-swing" Color="primary" OnClick="ToTopAsync">
        <MIcon>mdi-chevron-up</MIcon>
    </MButton>
</FabTransition>

@code {

    [Inject]
    MasaBlazor MasaBlazor { get; set; } = null!;

    [Inject]
    public IJSRuntime Js { get; set; } = null!;

    [CascadingParameter]
    private BaseLayout BaseLayout { get; set; } = null!;

    private bool? _showDrawer;
    private bool _showBackTop;
    private long _scrollEventId;

    private int Offset => AppService.AppBarHeight + 12;

    protected override void OnInitialized()
    {
        base.OnInitialized();

        BaseLayout.OnAppBarNavIconClick = () => _showDrawer = !_showDrawer;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        BaseLayout.ShowAppBarNavIcon();

        if (firstRender)
        {
            _scrollEventId = await Js.AddHtmlElementEventListener("window", "scroll", OnScroll, false, new EventListenerExtras(0, 100));
        }
    }

    private async Task OnScroll()
    {
        var pageYOffset = await Js.GetWindowPageYOffsetAsync();
        var top = pageYOffset ?? 0;

        _showBackTop = top > 300;

        await InvokeAsync(StateHasChanged);
    }

    private async Task ToTopAsync()
    {
        await Js.InvokeVoidAsync("backTop");
    }

    public async ValueTask DisposeAsync()
    {
        try
        {
            await Js.RemoveHtmlElementEventListener(_scrollEventId);
        }
        catch (Exception)
        {
            // ignored
        }
    }

}
